#ifndef _DFA_BASE
#define _DFA_BASE

#include "Buffer.h"
#include "Dfa_base_str.h"
#include "Dlex.h"
#include "Lim_matrix.h"
#include "Set.h"
#include <iostream>
#include <climits>
namespace dfa_base {
	const int Err=INT_MAX;
	class Dfa_base {
	public:
		typedef int State_type;
		static const State_type Reject=Err;			// reject value
		enum Dfa_type {Start_dfa, Suffix_dfa, Normal_dfa, Start_suffix_dfa };
	public:
		Dfa_base(mylib::Buffer &in, dlex::Reg_def &def, std::ostream &err=std::cerr);
		Dfa_base(const State_type *tab, State_type start, bool start_ln);			// build from data
		~Dfa_base() {
			if(start_tab) {delete start_tab; start_tab=0;}
			if(entity_tab) { delete entity_tab; entity_tab = 0; }
			if(suffix_tab) { delete suffix_tab; suffix_tab = 0; }
		}
		class Err_reg {};
		class Err_input {};
		class Out_of_range {};
		class Out_of_mem {};
	public:
		State_type start_state() {return _start_state; }
		Dfa_type type();
		State_type start(int i, char c);	// move
		bool start_acc(State_type state){return start_acc_state.exist(state);}	// accepting
		bool start_line(){return _start_line;}			// existing start line
		
		State_type entity(int i, char c);	// c
		bool entity_acc(State_type state){return entity_acc_state.exist(state);}	// 

		State_type suffix(int i, char c);
		bool suffix_acc(State_type state){return suffix_acc_state.exist(state);}
		void write(std::ostream &out=std::cout);
		void display(std::ostream &out);
	private:
		Dfa_base(const Dfa_base &base) {}			//copy 
		Dfa_base &operator=(const Dfa_base &base) {}
	private :
		mylib::Lim_matrix<State_type> *start_tab;
		mylib::Set<State_type> start_acc_state;
		mylib::Lim_matrix<State_type> *entity_tab;
		mylib::Set<State_type> entity_acc_state;
		mylib::Lim_matrix<State_type> *suffix_tab;
		mylib::Set<State_type> suffix_acc_state;
		State_type _start_state;
		bool _start_line;
	};
}
#endif
